import os.path
from io import BytesIO
import mimetypes
import paramiko
import requests

from requests import Response
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Logger import Logger
from yat.test import macro
from yat.test import Node


class CommonApi:
    def __init__(self, token):
        self.headers = None
        self.log = Logger()
        self.comm_sh = CommonSH()
        self.token = token
        self.ip = f"https://{macro.DATAKIT_HOST}:{macro.DATAKIT_PORT}"

    def delete_host(self, host_id: str) -> Response:
        """
        datakit删除服务器
        :param host_id: host_id
        :return:
        """
        api = f'/host/{host_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def post_host_ping(self, data: dict) -> Response:
        """
        导入服务器前，连通性测试
        :param data:json格式服务器信息，模板：
            {"privateIp":"127.0.0.1","publicIp":"127.0.0.1","port":"22","password":"123","username":"user"}
        :return:
        """
        api = '/host/ping'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        self.log.info(self.headers)
        url = self.ip + api
        self.log.info(url)
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def post_host(self, data: dict) -> Response:
        """
        服务器管理，新增服务器
        :param data:json格式服务器信息
        :return:
        """
        api = '/host'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_host_page(self, name: str = '', tag_ids: str = '',
                      system_os: str = '', page_num: int = 1,
                      page_size: int = 10) -> Response:
        """
        服务器管理界面，查询服务器
        :param name: 按服务器ip查询
        :param tag_ids: 按标签查询
        :param system_os: 按操作系统查询
        :param page_num: 查询第几页的服务器
        :param page_size: 每页最大服务器数量，为10的倍数
        :return: 返回状态码和查询到的服务器信息
        """
        api = f'/host/page?name={name}&tagIds={tag_ids}&os={system_os}&pageNum={page_num}&pageSize={page_size}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        self.log.info(url)
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_hostUser(self, data: dict) -> Response:
        """
        服务器新增用户
        :param data: json格式用户信息
        :return:
        """
        api = '/hostUser'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def delete_hostUser(self, host_user_id: str) -> Response:
        """
        删除服务器用户
        :param host_user_id: 服务器用户id
        :return:
        """
        api = f'/hostUser/{host_user_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def put_host(self, host_id: str, data: dict) -> Response:
        """
        编辑服务器信息
        :param host_id: 服务器id，hostId
        :param data: 修改后的服务器信息
        :return:
        """
        api = f'/host/{host_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def put_hostUser(self, host_user_id: str, data: dict) -> Response:
        """
        编辑用户
        :param data: 修改后的用户信息
        :param host_user_id: 用户id，hostUserId
        :return:
        """
        api = f'/hostUser/{host_user_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def post_jdbcDbClusterNode_ping(self, data: dict) -> Response:
        """
        添加实例时，联通性测试
        :param data:实例信息，json格式
        :return:响应结果
        """
        api = '/jdbcDbClusterNode/ping'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def post_jdbcDbCluster_add(self, data: dict) -> Response:
        """
        添加实例
        :param data: 实例信息，json格式
        :return:
        """
        api = '/jdbcDbCluster/add'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def delete_jdbcDbCluster(self, cluster_node_id: str) -> Response:
        """
        删除实例
        :param cluster_node_id: clusterNodeId
        :return:
        """
        api = f'/jdbcDbClusterNode/{cluster_node_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def put_jdbcDbCluster(self, cluster_id: str, data: dict) -> Response:
        """
        修改实例
        :param cluster_id: clusterId集群id
        :param data: 修改后的数据库集群信息
        :return:
        """
        api = f'/jdbcDbCluster/{cluster_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_jdbcDbCluster_page(self, name: str = '', ip: str = '', db_type: str = '',
                               page_num: int = 1, page_size: int = 10) -> Response:
        """
        查询实例列表
        :param name: 集群名称
        :param ip: ip地址
        :param db_type: 数据库类型
        :param page_num: 第几页
        :param page_size: 每页最大实例数
        :return:
        """
        api = f'/jdbcDbCluster/page?name={name}&&ip={ip}&type={db_type}&pageNum={page_num}&pageSize={page_size}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_hostUser_page(self, host_id: str):
        """
        查询服务器用户列表
        :param host_id:服务器Id，hostId
        :return:
        """
        api = f'/hostUser/page/{host_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_system_plugins_uninstall(self, plugin_name: str) -> Response:
        """
        卸载插件
        :param plugin_name: 插件名
        :return:
        """
        api = f"/system/plugins/uninstall/{plugin_name}"
        self.headers = {
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, headers=self.headers, verify=False)
        return response

    def post_system_plugins_offline_install(self, jar_file: str, node_name: str = 'Datakit') -> Response:
        """
        安装插件
        :param jar_file: jar文件绝对路径
        :param node_name:
        :return:
        """
        node = Node(f'{node_name}')
        jar_name = os.path.basename(jar_file)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(node.ssh_host, username=node.ssh_user, password=node.ssh_password)
        sftp = ssh.open_sftp()

        api = "/system/plugins/offline_install"
        self.headers = {
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        file_buffer = BytesIO()
        with sftp.file(jar_file, 'rb') as remote_file:
            file_buffer.write(remote_file.read())
        file_buffer.seek(0)
        files = {'file': (jar_name, file_buffer, 'application/java-archive')}
        response = requests.post(url=url, files=files, headers=self.headers, verify=False)
        ssh.close()
        return response

    def post_system_plugins_start(self, plugin_name: str) -> Response:
        """
        启动插件
        :param plugin_name: 插件名称
        :return: 响应状态码
        """
        api = f"/system/plugins/start/{plugin_name}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, headers=self.headers, verify=False)
        return response

    def post_system_plugins_stop(self, plugin_name: str) -> Response:
        """
        启动插件
        :param plugin_name: 插件名称
        :return: 响应状态码
        """
        api = f"/system/plugins/stop/{plugin_name}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, headers=self.headers, verify=False)
        return response

    def get_system_plugins_list(self, plugin_id: str = '', plugin_status: str = '') -> Response:
        """
        插件管理页面搜索功能
        :param plugin_status: 插件状态
        :param plugin_id: 插件名
        :return:
        """
        api = f"/system/plugins/list?pluginId={plugin_id}&pluginStatus={plugin_status}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_system_settings(self):
        """
        datakit右上角获取系统设置
        :return:
        """
        api = "/system/setting"
        url = self.ip + api
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_system_user(self, data: dict) -> Response:
        """
        添加账户
        :param data:账户信息
        :return:
        """
        api = '/system/user'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_system_user_list(self, page_num: int = 1, page_size: int = 10, user_name: str = '', phone_number: str = '',
                             status: int = '') -> Response:
        """
        用户查询
        :param user_name: 用户名
        :param phone_number: 电话号码
        :param status: 用户状态
        :param page_num: 页数
        :param page_size: 每页最大用户数
        :return:
        """
        api = f'/system/user/list?pageNum={page_num}&pageSize={page_size}&userName={user_name}&phonenumber={phone_number}&status={status}'
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def delete_system_user(self, user_id: int) -> Response:
        """
        删除用户
        :param user_id: 用户id
        :return:
        """
        api = f'/system/user/{user_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def put_system_user_resetPwd(self, data: dict) -> Response:
        """
        修改密码
        :param data: {"userId": ,"password":""}
        :return:
        """
        api = '/system/user/resetPwd'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_system_log(self) -> Response:
        """
        获取系统日志配置信息
        :return: 响应状态码和日志配置信息
        """
        api = "/system/log"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_system_log(self, data: dict) -> Response:
        """
        设置日志配置
        :param data: 日志配置
        :return:
        """
        api = "/system/log"
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_system_log_download(self, filename: str) -> Response:
        """
        下载系统日志
        :param filename: 日志文件名
        :return:
        """
        api = f"/system/log/download?filename={filename}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token,
            "charset": "utf-8"
        }
        url = self.ip + api
        response = requests.get(url, headers=self.headers, verify=False)
        return response

    def get_system_log_files(self) -> Response:
        """
        获取日志文件列表
        :return: 响应状态码和日志文件列表
        """
        api = "/system/log/files"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_system_operlog_list(self, business_type: str = '', oper_name: str = '', page_num: int = 1,
                                page_size: int = 10,
                                title: str = '', status: str = '') -> Response:
        """
        获取系统日志列表
        :param business_type: 操作类型(其他:0,新增:1,修改:2,删除:3,授权:4,启动:5,停止:6,安装:7,卸载:8)
        :param oper_name: 操作人员名称
        :param page_num: 页数
        :param page_size: 每页最大日志数量
        :param title: 系统模块
        :param status: HTTP状态
        :return:
        """
        api = f'''/system/operlog/list?businessType={business_type}&operName={oper_name}&pageNum={page_num}&pageSize={page_size}&status={status}&title={title}'''
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        self.log.info(url)
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_system_role(self, data) -> Response:
        """
        添加系统角色
        :param data: 角色权限信息
        :return:
        """
        api = "/system/role"
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_system_role_list(self, page_num: int = 1, page_size: int = 10, role_name: str = '',
                             status: str = '') -> Response:
        """
        搜索角色列表
        :param page_num: 页数
        :param page_size: 每页最大角色数
        :param role_name: 角色名
        :param status: 角色状态
        :return:
        """
        api = f"/system/role/list?pageNum={page_num}&pageSize={page_size}&roleName={role_name}&status={status}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def get_getRouters(self) -> Response:
        """
        获取左边框栏菜单
        :return:
        """
        api = "/getRouters"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def delete_system_role(self, role_id: int) -> Response:
        """
        删除系统角色
        :param role_id: 角色id
        :return:
        """
        api = f"/system/role/{role_id}"
        self.headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def put_system_user_profile_updatePwd(self, data: dict) -> Response:
        """
        用户更新密码
        :param data: 新旧加密后密码
        :return:
        """
        api = f'/system/user/profile/updatePwd'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_jdbcDbCluster_downloadTemplate(self) -> Response:
        """
        导入实例的文件模板
        :return: 模板内容
        """
        api = '/jdbcDbCluster/downloadTemplate'
        self.headers = {
            "Authorization": "Bearer " + self.token,
            "charset": "utf-8"
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_jdbcDbCluster_importAnalysis(self, file_path: str, node_name: str) -> Response:
        """
        通过csv文件批量导入实例
        :param node_name: 文件保存节点
        :param file_path: csv文件路径
        :return: 批量导入结果
        """
        node = Node(f'{node_name}')
        file_name = os.path.basename(file_path)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(node.ssh_host, username=node.ssh_user, password=node.ssh_password)
        sftp = ssh.open_sftp()

        api = '/jdbcDbCluster/importAnalysis'
        self.headers = {
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        file_buffer = BytesIO()
        with sftp.file(file_path, 'rb') as remote_file:
            file_buffer.write(remote_file.read())
        file_buffer.seek(0)
        mime_type, _ = mimetypes.guess_type(file_name)
        if mime_type is None:
            mime_type = 'application/octet-stream'
        files = {"file": (file_name, file_buffer, mime_type)}
        response = requests.post(url=url, files=files, headers=self.headers, verify=False)
        return response

    def post_hostTag_add(self, data: dict) -> Response:
        """
        创建标签
        :param data: 标签信息{"id":"","name":"test"}
        :return:
        """
        api = '/hostTag/add'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def delete_hostTag_del(self, tag_id: str) -> Response:
        """
        删除标签
        :param tag_id: 标签id
        :return:
        """
        api = f'/hostTag/del/{tag_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response

    def get_hostTag_page(self, name: str = '', page_num: int = 1, page_size: int = 10) -> Response:
        """
        查询标签
        :param name: 标签名称
        :param page_num:
        :param page_size:
        :return:
        """
        api = f'/hostTag/page?name={name}&pageNum={page_num}&pageSize={page_size}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def put_hostTag_update(self, tag_id: str, data: dict) -> Response:
        """
        编辑标签
        :param tag_id: 标签ID
        :param data: 标签信息
        :return:
        """
        api = f'/hostTag/update/{tag_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def put_hostTag_addTag(self, data: dict) -> Response:
        """
        标签设置，服务器添加标签
        :param data: {"hostIds":[],"names":[]}服务器id,标签名称
        :return:
        """
        api = '/hostTag/addTag'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def put_hostTag_delTag(self, data: dict) -> Response:
        """
        标签设置，服务器删除标签
        :param data: {"hostIds":[],"names":[]}服务器id,标签名称
        :return:
        """
        api = '/hostTag/delTag'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_az_hasName(self, az_name: str) -> Response:
        """
        查看新增的az名称是否已存在
        :param az_name: az名称
        :return:
        """
        api = f'/az/hasName?name={az_name}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def post_az(self, data: dict) -> Response:
        """
        新增az
        :param data: az信息
        :return:
        """
        api = '/az'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.post(url=url, json=data, headers=self.headers, verify=False)
        return response

    def get_az_page(self, name: str = '', page_num: int = 1, page_size: int = 10) -> Response:
        """
        查询az
        :param name:az名称
        :param page_num:
        :param page_size:
        :return:
        """
        api = f'/az/page?name={name}&pageNum={page_num}&pageSize={page_size}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.get(url=url, headers=self.headers, verify=False)
        return response

    def put_az(self, az_id: str, data: dict) -> Response:
        """
        编辑az
        :param az_id:
        :param data: az信息
        :return:
        """
        api = f'/az/{az_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.put(url=url, json=data, headers=self.headers, verify=False)
        return response

    def delete_az(self, az_id: str) -> Response:
        """
        编辑az
        :param az_id:
        :return:
        """
        api = f'/az/{az_id}'
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + self.token
        }
        url = self.ip + api
        response = requests.delete(url=url, headers=self.headers, verify=False)
        return response
